from apps.pay.order.baseViews import *
from apps.pay.order.sceneHandle import createOrderScene, setPayMoney, cancelOrderReturnScene, beforeCreateOrderScene
from apps.common.utils.time import getFormatTime
from apps.pay.order.service_exportExcel import exportExcel
from apps.pay.order.service_exportExcelForSendItem import exportExcelForSendItem
from apps.pay.order.service_exportExcelForWx import exportExcelForWx
from apps.pay.order.service_exportExcelForWxForExpressage import exportExcelForWxForExpressage
from apps.pay.recordIncomes.dao import RecordIncomesDao
from apps.system.user.dao import UserDao
from apps.pay.wx.service import returnMoney
from apps.merchant.sku.dao import SkuDao
from apps.system.kuaidi.dao import KuaidiDao
from apps.merchant.activity.dao import ActivityDao
from apps.chat.message.functions import MessageFun
from apps.pay.order.countAward.countProfit import countProfitFun
import tempfile
from django.http import FileResponse

class OrderShopViewSet(BaseOrderViewSet):
    def get_queryset(self):
        params = getRequestParams(self.request)
        _list = OrderDao().findAll().filter(shop__user=self.request.user)
        return _list

class OrderViewSet(BaseOrderViewSet):

    def get_queryset(self):
        params = getRequestParams(self.request)
        _list = getOrders(self).exclude(orderStatus='CANCEL')
        if params.get('routerName') == 'orderList':
            _list = OrderDao().findAllMainOrder()
        elif params.get('routerName') == 'suborder':
            _list = OrderDao().findAllSubOrder()
            _list = _list.filter(Q(scene='generay')|Q(scene='giftSection'),shop__types='0')
        elif params.get('routerName') == 'rechargeOrder':
            _list = _list.filter(Q(scene='recharge'))
        elif params.get('routerName') == 'payForFranchiseeOrder':
            _list = OrderDao().findAllSubOrder()
            _list = _list.filter(shop__types='1')
            if BaseDao().findRoleByAccount(self.request.user).key == '加盟店':
                _list = _list.filter(shop__admin=self.request.user)
        if BaseDao().findRoleByAccount(self.request.user).key == 'custom':
            _list = _list
            if params.get('orderStatus') == '':
                _list = _list.exclude(order__isnull=True)
            elif params.get('orderStatus') == 'WAIT_PAY' or params.get('orderStatus') == 'CANCEL':
                _list = _list.filter(order__isnull=True)
            else:
                _list = _list.exclude(order__isnull=True)
        else:
            _list = _list.exclude(user__isRobot=True)
        return _list

    '''创建订单'''

    @action(methods=['post'], detail=False)
    def createOrder(self, request):
        params = getRequestParams(request)
        if isEmptyStr(params.get("scene")):
            return Response(response_message('参数scene必填'))
        if isEmptyStr(params.get("sendType")):
            return Response(response_message('参数sendType必填'))
        if isEmptyStr(params.get("sendType")):
            return Response(response_message('参数sendType必填'))
        data = {
            "scene": params.get("scene"),
            "shop": params.get("shopId"),
            "user": request.user.id,
            "clientname": params.get("clientname"),
            "sendType": params.get("sendType"),
            'addrinfo': params.get('addrinfo'),
            'orderId': getFormatTime('%Y%m%d%H%M%S') + random_num(8),
            "remark": params.get("remark") if params.get("remark") else ''
        }
        # 校验
        res = beforeCreateOrderScene(params, data, request.user)
        if res.get('status') != 200:
            return Response(res.get('data'))
        
        # 设置实际支付金额
        res = setPayMoney(params, data, request.user)
        if res.get('status') == 200:
            data['sellingPrice'] = res.get('data').get('sellingPrice')
            data['costPrice'] = res.get('data').get('costPrice')
            data['realPay'] = res.get('data').get('realPay')
            data['discountParams'] = res.get('data').get('discountParams')
        else:
            return Response(res.get('data'))
        
        res = createOrderScene(params, data, request.user)
        return Response(res.get('data'))

    '''绑定代付人'''
    @action(methods=['post'], detail=False)
    def bindAnotherUser(self, request):
        params = getRequestParams(request)
        anotherUser = params.get('anotherUser')
        if not anotherUser:
            return Response(response_message('anotherUser参数必填'))
        order = OrderDao().findOneByOrderId(params.get('orderId'))
        anotherUser = UserDao().findOneByObjId(anotherUser)
        if order.anotherUser:
            return Response(response_action(10001, '该订单已绑定代付人'))

        order = OrderDao().update(order.id, {'anotherUser': anotherUser.id})
        orderItem = {}
        if order.content:
            contentDict = json.loads(order.content)
            if contentDict.get('orderItemList') and len(contentDict.get('orderItemList'))>0:
                orderItem = contentDict.get('orderItemList')[0]
        content = {
            'orderId': order.orderId,
            'realPay': str(order.realPay),
            'itemName': orderItem.get('itemName'),
        }
        print(111, order.user, anotherUser)
        MessageFun().sendMessage(request.user, anotherUser, 'custom', {'title': '我有一笔订单需要支付，请帮我付款！', 'contentType': 'anotherPay', 'content': json.dumps(content)})
        return Response(response_success('发送成功'))



    '''根据orderId获取订单详情'''

    @action(methods=['post'], detail=False)
    def getOrderInfoByOrderId(self, request):
        params = getRequestParams(request)
        orderId = params.get('orderId')
        if not orderId:
            return Response(response_message('orderId参数必填'))
        order = OrderDao().findOneByOrderId(orderId)
        model = OrderModelSerializer(order).data
        if order.anotherUser: # 如果代付人存在，从新计算实付
            if self.request.user.id == order.anotherUser.id:
                # 设置实际支付金额
                content = json.loads(order.content)
                res = setPayMoney({'orderItemList': content.get('orderItemList')}, {'scene':'generay'}, order.anotherUser)
                updateData = {}
                if res.get('status') == 200:
                    updateData['sellingPrice'] = res.get('data').get('sellingPrice')
                    updateData['costPrice'] = res.get('data').get('costPrice')
                    updateData['realPay'] = res.get('data').get('realPay')
                    contentDict = model.get('contentDict')
                    contentDict['discountParams'] = res.get('data').get('discountParams')
                    updateData['contentDict'] = contentDict
                print('updateData', updateData)
                model.update(updateData)
        return Response(response_success(model))

    '''发货'''

    @action(methods=['post'], detail=False)
    def sendItem(self, request):
        params = getRequestParams(request)
        order = OrderDao().findOneByOrderId(params.get('orderId'))
        if order.user.isRobot:
            return Response(response_message('机器人账户订单不能发货'))
        if order.orderStatus != 'WAIT_SEND':
            return Response(response_message('待发货状态才允许发货'))
        data = {'orderStatus': 'WAIT_RECEIVE'}
        if params.get('expressageinfo'):
            data['expressageinfo'] = params.get('expressageinfo')
            data['sendTime'] = datetime.datetime.now()
        OrderDao().update(order.id, data)
        MessageFun().sendMessage(None, order.user, 'jytz', {'title': '订单通知', 'content': '您的订单已发货'})
        return Response(response_success('操作成功'))

    '''完成订单'''
    @action(methods=['post'], detail=False)
    def finishOrder(self, request):
        params = getRequestParams(request)
        order = OrderDao().findOneByOrderId(params.get('orderId'))
        if order.user.isRobot:
            return Response(response_message('机器人账户订单不能完成'))
        if order.orderStatus != 'WAIT_RECEIVE':
            return Response(response_message('待收货状态才允许完成'))
        data = {'orderStatus': 'FINISH'}
        OrderDao().update(order.id, data)
        MessageFun().sendMessage(None, order.user, 'jytz', {'title': '订单通知', 'content': '您的订单已完成'})
        return Response(response_success('操作成功'))

    '''取消支付'''

    @action(methods=['post'], detail=False)
    def cancelPay(self, request):
        params = getRequestParams(request)
        orderId = params.get('orderId')
        if isEmptyStr(orderId):
            return Response(response_message('orderId参数缺失'))
        order = OrderDao().findOneByOrderId(orderId)
        if order.orderStatus != 'WAIT_PAY':
            return Response(response_message('待支付状态才允许取消'))
        OrderDao().update(order.id, {'orderStatus': 'CANCEL'})
        # 返还库存
        content = json.loads(order.content)
        for item in content.get('orderItemList'):
            if item.get('sku'):
                SkuDao().addStock(item.get('sku'), item.get('payCount'))
                # 返还库存
                content = json.loads(order.content)
                if content.get('orderItemList'):
                    for item in content.get('orderItemList'):
                        if item.get('sku'):
                            SkuDao().addStock(item.get('sku'), item.get('payCount'))
        MessageFun().sendMessage(None, order.user, 'jytz', {'title': '订单通知', 'content': '订单已取消'})
        return Response(response_success('取消成功'))

    '''取消订单'''
    @action(methods=['post'], detail=False)
    def cancelOrder(self, request):
        params = getRequestParams(request)
        orderId = params.get('orderId')
        if isEmptyStr(orderId):
            return Response(response_message('orderId参数缺失'))
        order = OrderDao().findOneByOrderId(orderId)
        if order.orderStatus != 'WAIT_SEND':
            return Response(response_message('待发货状态才允许取消'))

        if not order.activity:
            # 取消订单之后
            if order.payway == 'wxpay':
                # 退还款项到微信账户
                OrderDao().update(order.id, {'orderStatus': 'RETURNING', 'retunMoneyTime': datetime.datetime.now()})
                returnMoney(params)
            else:
                OrderDao().update(order.id, {'orderStatus': 'RETURNING', 'retunMoneyTime': datetime.datetime.now()})
                # 退还积分
                UserDao().addWallet('incomes', order.user, order.realPay)
                data = {}
                data['scene'] = 'expenseReturn'
                data['user'] = order.user.id
                data['fromUser'] = order.user.id
                data['orderId'] = order.orderId
                data['money'] = order.realPay
                data['payway'] = 'incomes'
                data['changeWay'] = 'add'
                data['orderStatus'] = 'FINISH'
                RecordIncomesDao().create(data)
                OrderDao().update(order.id, {'orderStatus': 'HAS_RETURN'})
            cancelOrderReturnScene(order.orderId)

        return Response(response_success('取消成功'))

    '''导出订单'''

    @action(methods=['post'], detail=False)
    def exportExcel(self, request):
        params = getRequestParams(request)
        _orders = OrderDao().findAll().exclude(orderStatus='CANCEL')
        if type(params.get('ids')) == list and len(params.get('ids'))>0:
            _orders = _orders.filter(id__in=params.get('ids'))
            output = exportExcel(_orders)
            return FileResponse(output, as_attachment=True)
        if params.get('routerName') == 'orderList':
            _orders = _orders.filter(Q(scene='generay')|Q(scene='giftSection')).filter(order__isnull=True)
        elif params.get('routerName') == 'suborder':
            _orders = _orders.filter(Q(scene='generay')|Q(scene='giftSection')).exclude(order__isnull=True)
        
        # 查询出要导出的数据
        query_params = {}
        exclude_params = {}
        if params.get('orderId'):
            query_params['orderId'] = params.get('orderId')
        if params.get('user'):
            query_params['user'] = params.get('user')
        if params.get('sendType'):
            query_params['sendType'] = params.get('sendType')
        if params.get('payway'):
            query_params['payway'] = params.get('payway')
        if params.get('orderStatus'):
            query_params['orderStatus'] = params.get('orderStatus')
        query_params['createTime__gte'] = params.get('startTime') if params.get(
            'startTime') else datetime.datetime.now() - datetime.timedelta(days=30)
        query_params['createTime__lte'] = params.get('endTime') if params.get(
            'endTime') else datetime.datetime.now() + datetime.timedelta(days=1)

        _orders = _orders.filter(**query_params).exclude(**exclude_params)
        output = exportExcel(_orders)
        return FileResponse(output, as_attachment=True)
    
    '''导出批量发货订单'''
    @action(methods=['post'], detail=False)
    def exportExcelForSendItem(self, request):
        params = getRequestParams(request)
        _orders = OrderDao().findAll().exclude(orderStatus='CANCEL')
        if type(params.get('ids')) == list and len(params.get('ids'))>0:
            _orders = _orders.filter(id__in=params.get('ids'))
            output = exportExcelForSendItem(_orders)
            return FileResponse(output, as_attachment=True)
        
        if params.get('routerName') == 'orderList':
            _orders = _orders.filter(Q(scene='generay')|Q(scene='giftSection')).filter(order__isnull=True)
        elif params.get('routerName') == 'suborder':
            _orders = _orders.filter(Q(scene='generay')|Q(scene='giftSection')).exclude(order__isnull=True)

        # 查询出要导出的数据
        query_params = {}
        exclude_params = {}
        if params.get('orderId'):
            query_params['orderId'] = params.get('orderId')
        if params.get('user'):
            query_params['user'] = params.get('user')
        if params.get('sendType'):
            query_params['sendType'] = params.get('sendType')
        if params.get('payway'):
            query_params['payway'] = params.get('payway')
        if params.get('orderStatus'):
            query_params['orderStatus'] = params.get('orderStatus')
        query_params['createTime__gte'] = params.get('startTime') if params.get(
            'startTime') else datetime.datetime.now() - datetime.timedelta(days=30)
        query_params['createTime__lte'] = params.get('endTime') if params.get(
            'endTime') else datetime.datetime.now() + datetime.timedelta(days=1)

        _orders = _orders.filter(**query_params).exclude(**exclude_params)
        output = exportExcelForSendItem(_orders)
        return FileResponse(output, as_attachment=True)
    
    '''导入批量发货订单'''
    @action(methods=['post'], detail=False)
    def importExcelForSendItem(self, request):
        params = getRequestParams(request)
        fp = request.FILES.get('file')
        if not fp:
            return Response(response_action('10002', '文件上传为空'))
        # 保存文件到临时文件
        with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(fp.name)[1]) as temp_file:
            for chunk in fp.chunks():
                temp_file.write(chunk)
            temp_file_path = temp_file.name
        
        try:
            # 打开Excel文件
            workbook = xlrd.open_workbook(temp_file_path)
            # 获取第一个工作表
            worksheet = workbook.sheet_by_index(0)
            
            _errors = ''
            # 表头
            titles = ['订单号', '快递公司', '快递单号']
            headers = []
            for col in range(0, worksheet.ncols):
                value = worksheet.cell_value(0, col)
                # print('第一行的数据', value)
                headers.append(value)
            for col in range(0, len(titles)):
                # print('表头', titles[col])
                if titles[col] not in headers:
                    _errors = _errors + '表头"' + titles[col] + '"不存在；'
            
            
            # 遍历每一行
            data = []
            for row in range(1, worksheet.nrows):
                row_data = {}
                for col in range(0, len(headers)):
                    value = worksheet.cell_value(0, col)
                    # print('第一行的数据', value)
                    if value in titles:
                        if not worksheet.cell_value(row, col) and col!=0:
                            _errors = _errors + '第' + str(row) + '行' + headers[col] + '数据不存在；'
                        row_data[value] = worksheet.cell_value(row, col)
                        row_data['rowIndex'] = row
                data.append(row_data)

            if len(_errors) > 0:
                return Response(response_action(10002, _errors))
            # 校验数据----------------------------------
            orderId = ''
            for order_data in data:
                # 这里可以根据 order_data 创建订单或其他操作
                if order_data.get('订单号'):
                    orderId = order_data.get('订单号')
                else:
                    order_data['订单号'] = orderId
                _order = OrderDao().findOneByOrderId(orderId)
                if not _order:
                    _errors = _errors + '第' + str(order_data.get('rowIndex')) + '行' + '订单号不存在；'
                    continue
                
                if _order.user.isRobot:
                    _errors = _errors + '第' + str(order_data.get('rowIndex')) + '行' + '机器人账户订单不能发货；'
                    continue
                if _order.orderStatus != 'WAIT_SEND':
                    _errors = _errors + '第' + str(order_data.get('rowIndex')) + '行' + '待发货状态才允许发货；'
                    continue
                kusidis = KuaidiDao().findAll().filter(name=order_data.get('快递公司'))
                if not kusidis.exists():
                    _errors = _errors + '第' + str(order_data.get('rowIndex')) + '行' + '快递公司名称错误；'
                    continue
            if len(_errors) > 0:
                return Response(response_action(10002, _errors))
            # 修改数据----------------------------------
            for order_data in data:
                _order = OrderDao().findOneByOrderId(order_data.get('订单号'))
                expressageinfoDict = {}
                expressageinfoDict['expressageCompany'] = order_data.get('快递公司')
                expressageinfoDict['expressageNum'] = order_data.get('快递单号')
                OrderDao().update(_order.id, {'expressageinfo': json.dumps(expressageinfoDict), 'orderStatus': 'WAIT_RECEIVE', 'sendTime': datetime.datetime.now()})
                MessageFun().sendMessage(None, _order.user, 'jytz', {'title': '订单通知', 'content': '您的订单已发货'})
        except Exception as e:
            print('导入失败', e)
            return Response(response_message('导入错误'))
        return Response(response_success_notScrypt('操作成功'))

    '''微信订单转换'''
    @action(methods=['post'], detail=False)
    def importExcelForWx(self, request):
        params = getRequestParams(request)
        fp = request.FILES.get('file')
        if not fp:
            return Response(response_action('10002', '文件上传为空'))
        # output = exportExcelForWxForExpressage(fp)
        output = exportExcelForWx(fp)
        return FileResponse(output, as_attachment=True)


    # 更新物流信息
    @action(methods=['post'], detail=False)
    def updateExpressageNum(self, request):
        params = getRequestParams(request)
        if not params.get('orderId'):
            return Response(response_message('orderId参数缺失'))
        order = OrderDao().findOneByOrderId(params.get('orderId'))
        if params.get('expressageinfo'):
            OrderDao().update(order.id, {
                'expressageinfo': params.get('expressageinfo')
            })
        if params.get('addrinfo'):
            OrderDao().update(order.id, {
                'addrinfo': params.get('addrinfo')
            })
        return Response(response_success('操作成功'))
    
    # 批量计算利润
    @action(methods=['post'], detail=False)
    def countProfit(self, request):
        params = getRequestParams(self.request)
        _skuList = params.get('skuList')
        _activityId = params.get('activityId')
        if not _activityId:
                return Response(response_message('请选择功能类型'))
        for sku in _skuList:
            if not sku.get('sellingPrice'):
                return Response(response_message('请填写销售价'))
            if not sku.get('costPrice'):
                return Response(response_message('请填写成本价'))
            data = countProfitFun({'sellingPrice': sku.get('sellingPrice'), 'costPrice': sku.get('costPrice'), 'activityId': _activityId})
            sku.update(data)
        return Response(response_success({'skuList': _skuList}))

